Python copy模块
引用
变量保存字符串和整数值。
>>> spam = 42
>>> cheese = spam
>>> spam = 100
>>> spam
100
>>> cheese
42
将 42 赋给 spam 变量, 然后拷贝 spam 中的值, 将它赋给变量 cheese。当稍后将 spam 中的值改变为 100 时, 这不会影响 cheese 中的值。这是因为 spam 和 cheese是不同的变量, 保存了不同的值。
但列表不是这样的。 当你将列表赋给一个变量时,实际上是将列表的“引用”赋给了该变量。引用是一个值,指向某些数据。列表引用是指向一个列表的值。这里有一些代码,让这个概念更容易理解。
#1
>>> spam = [0, 1, 2, 3, 4, 5]
#2
>>> cheese = spam
#3
>>> cheese[1] = 'Hello!'
>>> spam
[0, 'Hello!', 2, 3, 4, 5]
>>> cheese
[0, 'Hello!', 2, 3, 4, 5]
当创建列表时1,你将对它的引用赋给了变量。但下一行2只是将 spam 中的列表引用拷贝到 heese,而不是列表值本身。这意味着存储在 spam 和 cheese 中的值,现在指向了同一个列表。底下只有一个列表,因为列表本身实际从未复制。所以当你修改 cheese 变量的第一个元素时3,也修改了 spam 指向的同一个列表。
变量包含对列表值的引用, 而不是列表值本身。但对于字符串和整数值, 变量就包含了字符串或整数值。在变量必须保存可变数据类型的值时, 例如列表或字典,Python 就使用引用。对于不可变的数据类型的值, 例如字符串、 整型或元组, Python变量就保存值本身。 虽然 Python 变量在技术上包含了对列表或字典值的引用,但人们通常随意地说,该变量包含了列表或字典。
copy 模块
copy()
和 deepcopy()
函数
在处理列表和字典时,尽管传递引用常常是最方便的方法, 但如果函数修改了传入的列表或字典, 你可能不希望这些变动影响原来的列表或字典。要做到这一点,Python 提供了名为copy 的模块
, 其中包含copy()和 deepcopy()函数
。
copy.copy()
第一个函数copy.copy(), 可以用来复制列表或字典这样的可变值, 而不只是复制引用。在交互式环境中输入以下代码
>>> import copy
>>> spam = ['A', 'B', 'C', 'D']
>>> cheese = copy.copy(spam)
>>> cheese[1] = 42
>>> spam
['A', 'B', 'C', 'D']
>>> cheese
['A', 42, 'C', 'D']
现在 spam 和 cheese 变量指向独立的列表, 这就是为什么当你将 42 赋给下标 7时, 只有 cheese 中的列表被改变。
copy.deepcopy()
如果要复制的列表中包含了列表, 那就使用 copy.deepcopy()函数来代替
deepcopy()
函 数将同时复制它们内部的列表。